package com.apexsoft.aas.service.model;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.parser.Feature;
import com.apexsoft.aas.service.grpc.FastjsonGrpcSupport;

import java.io.Serializable;
import java.util.*;

/**
 * AResponse通用响应包
 *
 * @author lowezheng
 * @version 1.0.0, 19/01/30
 */
@Deprecated
public class AResponse implements Serializable {

    /**
     * Field  状态码
     * <p>
     * >0 ,成功
     * <0 ,失败
     */
    private Integer code;

    /**
     * Field  响应说明
     */
    private String note;

    /**
     * Field  错误码
     */
    private Integer errcode = 0;

    /**
     * Field  耗时(毫秒)
     */
    private String duration;

    /**
     * Field  总页数
     */
    private Long totalPage = -1L;

    /**
     * Field  总记录数
     */
    private Long totalRecord = -1L;
    /**
     * Field  数据包头部
     */
    private Map<String, String> heads;

    /**
     * Field  结果数组
     */
    private List<Map<String, Object>> records;

    /**
     * Field  结果对象
     */
    private Map<String, Object> data;

    /**
     * GRPC的json字符串还原回会resp对象
     *
     * @return
     * @throws
     */
    public static AResponse buildFromGRPCJson(String grpcJson) {
        return JSON.parseObject(
                grpcJson, AResponse.class,
                FastjsonGrpcSupport.getParserConfig(),
                Feature.SupportAutoType);

    }

    public JSONObject toJson() {
        JSONObject json = new JSONObject();
        if (this.code != null) {
            json.put("code", code);
        }
        if (this.note != null) {
            json.put("note", note);
        }
        if (this.errcode != null) {
            json.put("errcode", errcode);
        }
        if (this.duration != null) {
            json.put("duration", duration);
        }
        if (this.totalPage != null) {
            json.put("totalPage", totalPage);
        }
        if (this.totalRecord != null) {
            json.put("totalRecord", totalRecord);
        }
        if (this.heads != null) {
            JSONObject headJson = JSONObject.parseObject(JSON.toJSONString(this.heads));
            json.put("heads", headJson);
        }
        if (this.data != null) {
            JSONObject dataJson = JSONObject.parseObject(JSON.toJSONString(this.data));
            json.put("data", dataJson);
        }
        if (this.records != null) {
            JSONArray listJson = new JSONArray();
            for (Map<String, Object> row : this.records) {
                JSONObject rowJson = JSONObject.parseObject(JSON.toJSONString(row));
                listJson.add(rowJson);
            }
            json.put("records", listJson);
        }
        return json;
    }

    public void addHead(String key, String value) {
        if (heads == null) {
            heads = new HashMap<>();
        }
        heads.put(key, value);
    }

    public void removeHead(String key) {
        if (heads != null) {
            heads.remove(key);
        }
    }

    public void addData(String key, Object value) {
        if (data == null) {
            data = new HashMap<>();
        }
        data.put(key, value);
    }

    public void removeData(String key) {
        if (data != null) {
            data.remove(key);
        }
    }

    public void addRecord(Map<String, Object> map) {
        if (records == null) {
            records = new ArrayList<>();
        }
        records.add(map);
    }


    public <T> T getDataEx(String key, Class<T> cls) {
        if (data != null) {
            Object o = data.get(key);
            //防止JSONObject转成自己
            if (o == null) {
                return null;
            } else if (o instanceof JSONObject && cls != JSONObject.class) {
                return ((JSONObject) o).toJavaObject(cls);
            } else if (o.getClass() == cls) {
                return (T) o;
            } else {
                throw new RuntimeException("key value class: " + o.getClass().getName() + ", not match target class:" + cls.getName());
            }

        } else {
            return null;
        }

    }

    public <T> T getDataEx(Class<T> cls) {
        return (T) new JSONObject(data).toJavaObject(cls);
    }

    public <T> List<T> getRecordsEx(Class<T> cls) {
        List<T> list = new ArrayList<>();
        if (records != null) {
            for (Map<String, Object> o : records) {
                list.add(((JSONObject) JSON.toJSON(o)).toJavaObject(cls));
            }
        }
        return list;
    }

    public void setRecordsEx(List<?> list) {
        records = new ArrayList<>();
        for (Object t : list) {
            records.add(((JSONObject) JSON.toJSON(t)).toJavaObject(Map.class));
        }
    }

    @JSONField(serialize = false, deserialize = false)
    public boolean isSuccess() {
        if (this.code != null && this.code > 0) {
            return true;
        }
        return false;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }

    public Integer getErrcode() {
        return errcode;
    }

    public void setErrcode(Integer errcode) {
        this.errcode = errcode;
    }

    public String getDuration() {
        return duration;
    }

    public void setDuration(String duration) {
        this.duration = duration;
    }

    public Long getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(Long totalPage) {
        this.totalPage = totalPage;
    }

    public Long getTotalRecord() {
        return totalRecord;
    }

    public void setTotalRecord(Long totalRecord) {
        this.totalRecord = totalRecord;
    }

    public Map<String, String> getHeads() {
        return heads;
    }

    public void setHeads(Map<String, String> heads) {
        this.heads = heads;
    }

    public List<Map<String, Object>> getRecords() {
        return records;
    }

    public void setRecords(List<Map<String, Object>> records) {
        this.records = records;
    }

    public Map<String, Object> getData() {
        return data;
    }

    public void setData(Map<String, Object> data) {
        this.data = data;
    }
}

